﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class RobotTouch : MonoBehaviour, IResettable, ITouchable {

    private Vector3 touchLocation = Vector3.zero;
    private Vector3 releaseLocation = Vector3.zero;

    private GameUIState weaponSelection = null;

    public GameObject energyShot;
    public GameObject teleportShot;
    public GameObject missile;

    public float minimumDragForShot = 0.5f;
    public float shotStartDistance = 1.0f;
    public float maxTargetDistance = 2.0f;

    public float energyShotPowerFactor = 200.0f;

    private Vector3 originalPosition;
    private Quaternion originalRotation;

    private Transform targetReticle = null;
    private Transform cancelShot = null;

    public List<GameObject> shotMarkers = new List<GameObject>();

    private ShotSelectButton energyShotButton;
    private ShotSelectButton teleportShotButton;
    private ShotSelectButton missileShotButton;

    private bool shotCycleBegun = false;

    public int maxEnergyShotReserve = 9;
    public int maxMissileReserve = 4;

    public int energyShotReserve = 9;
    public int missileReserve = 4;
    
    // Use this for initialization
	void Start () {

        weaponSelection = GameObject.FindGameObjectWithTag("uiElements").GetComponent<GameUIState>();

        originalPosition = transform.parent.position;
        originalRotation = transform.parent.rotation;

        targetReticle = this.transform.parent.FindChild("targetReticle");
        cancelShot = this.transform.parent.FindChild("cancelShot");

        targetReticle.renderer.enabled = false;
        cancelShot.renderer.enabled = false;

        energyShotButton = GameObject.Find("UIElements").transform.FindChild("energyShotButton").GetComponent<ShotSelectButton>();
        teleportShotButton = GameObject.Find("UIElements").transform.FindChild("teleportShotButton").GetComponent<ShotSelectButton>();
        missileShotButton = GameObject.Find("UIElements").transform.FindChild("missileButton").GetComponent<ShotSelectButton>();

        energyShotButton.shotCount = energyShotReserve;
        teleportShotButton.shotCount = int.MaxValue;    // Be my guest. Fire 2 billion teleport shots. You've got 190 years.
        missileShotButton.shotCount = missileReserve;

        ResetItemList.Instance.AddItem(this);
        TouchableList.Instance.AddItem(this);

        FollowActionPriorityQueue.Instance.AddFollowPosition(new RobotPrioritizedFollowPosition(this));
    }
	
	// Update is called once per frame
	void Update () {

	}

    private GameObject GetSelectedShot()
    {
        switch (weaponSelection.selectedShotType)
        {
            case GameUIState.ShotType.EnergyShot:
                energyShotButton.OnShotFired();
                return energyShot;
            case GameUIState.ShotType.TeleportShot:
                teleportShotButton.OnShotFired();
                return teleportShot;
            case GameUIState.ShotType.Missile:
                missileShotButton.OnShotFired();
                return missile;
        }
        return null;
    }

    private bool CanShoot()
    {
        switch (weaponSelection.selectedShotType)
        {
            case GameUIState.ShotType.EnergyShot:
                return energyShotButton.CanFire();
            case GameUIState.ShotType.TeleportShot:
                return teleportShotButton.CanFire();
            case GameUIState.ShotType.Missile:
                return missileShotButton.CanFire();
        }
        return false;
    }

    public void Reset()
    {
        this.transform.parent.position = originalPosition;
        this.transform.parent.rotation = originalRotation;
        this.energyShotReserve = maxEnergyShotReserve;
        this.missileReserve = maxMissileReserve;

        energyShotButton.shotCount = maxEnergyShotReserve;
        teleportShotButton.shotCount = int.MaxValue;    
        missileShotButton.shotCount = maxMissileReserve;


        TouchEnabled = true;
    }

    public void OnTouch(Vector3 screenPosition, Vector3 worldPosition)
    {
        if (CanShoot())
        {
            shotCycleBegun = true;
            this.touchLocation = worldPosition;
        }
    }

    public bool HoldsTouch()
    {
        return true;
    }

    public void OnRelease(Vector3 screenPosition, Vector3 worldPosition)
    {
        if (!shotCycleBegun) return;

        shotCycleBegun = false;
        this.releaseLocation = worldPosition;

        targetReticle.renderer.enabled = false;
        cancelShot.renderer.enabled = false;

        Vector3 robotToTarget = releaseLocation - touchLocation;
        if (robotToTarget.magnitude < minimumDragForShot)
        {
            return;
        }
        if (robotToTarget.magnitude > Vector3.Distance(this.transform.position, targetReticle.position))
        {
            float trueMagnitude = Vector3.Distance(this.transform.position, targetReticle.position);
            robotToTarget.Normalize();
            robotToTarget *= trueMagnitude;
        }

        foreach (GameObject shotMarker in shotMarkers)
        {
            Destroy(shotMarker);
        }
        shotMarkers.Clear();

        GameObject shotToSpawn = GetSelectedShot();
        GameObject newShot = null;
        switch (shotToSpawn.tag)
        {
            case "energyShot":
                if (energyShotReserve > 0)
                {
                    energyShotReserve--;
                    newShot = GameObject.Instantiate(shotToSpawn, this.transform.position + robotToTarget.normalized * shotStartDistance, Quaternion.identity) as GameObject;
                    newShot.GetComponent<EnergyShotManager>().owner = this.gameObject;

                    if (energyShotReserve <= 0)
                    {
                        if (missileReserve > 0)
                            missileShotButton.Select();
                        else
                            teleportShotButton.Select();
                    }
                }
                break;
            case "missile":
                if (missileReserve > 0)
                {
                    missileReserve--;
                    newShot = GameObject.Instantiate(shotToSpawn, this.transform.position + robotToTarget.normalized * shotStartDistance, Quaternion.identity) as GameObject;

                    if (missileReserve <= 0)
                    {
                        if (energyShotReserve > 0)
                            energyShotButton.Select();
                        else
                            teleportShotButton.Select();
                    }

                }
                break;
            default:
                newShot = GameObject.Instantiate(shotToSpawn, this.transform.position + robotToTarget.normalized * shotStartDistance, Quaternion.identity) as GameObject;
                break;
        }

        if (newShot != null)
        {
            newShot.rigidbody.AddForce(robotToTarget * energyShotPowerFactor);
        }


    }

    public GameObject GetColliderObject()
    {
        return this.gameObject;
    }


    public void OnDrag(Vector3 screenPosition, Vector3 worldPosition)
    {
        if (!shotCycleBegun) return;

        Vector3 touchToDrag = worldPosition - this.transform.position;
        //print("touchToDrag " + touchToDrag.ToString());
        if (touchToDrag.magnitude > maxTargetDistance)
        {
            touchToDrag = touchToDrag.normalized * maxTargetDistance;
        }

        targetReticle.GetComponent<SpriteRenderer>().enabled = true;
        targetReticle.position = this.transform.position + touchToDrag;

        Vector3 cancelShotXY = Camera.main.ScreenToWorldPoint(new Vector3(0, 0));
        cancelShot.position = new Vector3(cancelShotXY.x, cancelShotXY.y, cancelShot.position.z);
        cancelShot.GetComponent<SpriteRenderer>().enabled = true;

        RaycastHit hitInfo;
        if (Physics.Raycast(Camera.main.ScreenPointToRay(screenPosition), out hitInfo))
        {
            if (hitInfo.collider.tag == "cancelShot")
            {
                OnShotCanceled();
            }
        }

    }

    private void OnShotCanceled()
    {
        shotCycleBegun = false;
        cancelShot.renderer.enabled = false;
        targetReticle.renderer.enabled = false;
    }

    public bool TouchEnabled { get; set; }

    public bool PersistAfterReset()
    {
        return true;
    }
}
